import {instantiate, isValid, Node, Prefab, UITransform} from "cc";
import {GObject} from "./GObject";
import {UIConfig} from "./UIConfig";
import {ByteBuffer} from "./utils/ByteBuffer";
import {ResImpl} from "../drongo/res/res/ResImpl";
import {Loader} from "../drongo/res/loaders/Loader";
import {Res} from "../drongo/res/Res";
import {URL2Key} from "../drongo/res/core/ResURL";
import {ResRef} from "../drongo/res/core/ResRef";

type ResInfo = { url: string, bundle: string, type: string | any }

export class GLoaderPrefab extends GObject {
    private _info: ResRef;
    private _url: ResInfo;
    private _container: Node;
    private _content: Node;

    public constructor() {
        super();

        this._node.name = "GLoaderPrefab";
        this._url = {url: "", type: "prefab", bundle: ""};

        this._container = new Node("Wrapper");
        this._container.layer = UIConfig.defaultUILayer;
        this._container.addComponent(UITransform).setAnchorPoint(0, 1);
        this._node.addChild(this._container);
    }

    public dispose(): void {
        super.dispose();
        this.clearContent();
    }

    public get url(): ResInfo {
        return this._url;
    }

    public set url(value: ResInfo) {
        if (this._url == value)
            return;

        this._url = value;
        this.loadContent();
        this.updateGear(7);
    }

    public get content(): Node {
        return this._content;
    }

    protected loadContent(): void {
        this.clearContent();

        if (!this._url)
            return;

        this.loadExternal();
    }

    protected loadExternal(): void {
        if (this._url.url.startsWith("http://")
            || this._url.url.startsWith("https://")
            || this._url.url.startsWith('/'))
            throw new Error("未实现")
        else
            Res.GetResRef(this._url, URL2Key(this._url)).then(this.onLoaded.bind(this));
    }

    private onLoaded(ref: ResRef): void {
        //因为是异步返回的，而这时可能url已经被改变，所以不能直接用返回的结果

        if (!this._url || !isValid(this._node))
            return;
        this._info = ref;
        this._content = instantiate(ref.content);
        this._container.addChild(this._content);
    }

    private clearContent(): void {
        if (this._content&& isValid(this._content)) {
            this._content.destroy();
            this._content = null;
        }
        if (this._info){
            this._info.Dispose()
        }
    }

    protected handleSizeChanged(): void {
        super.handleSizeChanged();
    }

    protected handleAnchorChanged(): void {
        super.handleAnchorChanged();
    }

    protected handleGrayedChanged(): void {
    }

    public getProp(index: number): any {
        return super.getProp(index)
    }

    public setProp(index: number, value: any): void {
        super.setProp(index, value);
    }

    public setup_beforeAdd(buffer: ByteBuffer, beginPos: number): void {
        super.setup_beforeAdd(buffer, beginPos);

        buffer.seek(beginPos, 5);

        this._url.url = buffer.readS();

        if (this._url.url)
            this.loadContent();
    }
}
